package com.liu.qqRobot.wm.handler;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.common.utils.HtmlToImageUtils;
import com.liu.common.utils.QQClientUtils;
import com.liu.common.utils.WmClientUtils;
import com.liu.mybatisPlus.q.service.QGroupUserOperationQuantityService;
import com.liu.mybatisPlus.wm.entity.base.WmLichWeapons;
import com.liu.mybatisPlus.wm.service.WmLichWeaponsService;
import com.liu.qqRobot.event.entity.dto.EventReportingDTO;
import com.liu.qqRobot.q.enums.OperationTypeEnum;
import com.liu.qqRobot.wm.entity.dto.WarframeMarketLichAuctionDTO;
import com.liu.qqRobot.wm.entity.dto.WarframeMarketLichAuctionTemplateDTO;
import com.liu.qqRobot.wm.enums.AuctionsSortByEnum;
import com.liu.qqRobot.wm.enums.LichElementEnum;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class WmlHandler {

    @Resource
    private WmLichWeaponsService wmLichWeaponsService;

    @Resource
    private QGroupUserOperationQuantityService qGroupUserOperationQuantityService;

    /**
     * 处理事件
     * @param data 信息内容
     * @param groupId 群号
     * @param userId 发送人QQ号
     */
    public void handler(EventReportingDTO.Message.Data data, Long groupId, Long userId, Boolean isGroup) {
        Integer page = 1;
        String text = data.getText();
        Map<String, Object> param = this.getParam(text, groupId, userId, isGroup);
        QueryWrapper<WmLichWeapons> wmLichWeaponsQueryWrapper = new QueryWrapper<>();
        wmLichWeaponsQueryWrapper.like("item_name", param.get("lichName"));
        List<WmLichWeapons> wmLichWeaponsList = wmLichWeaponsService.list(wmLichWeaponsQueryWrapper);
        if (wmLichWeaponsList.size() == 1) {
            WmLichWeapons wmLichWeapons = wmLichWeaponsList.get(0);
            List<WarframeMarketLichAuctionDTO> warframeMarketLichAuctionDTOList = WmClientUtils.getLichAuctions("lich", "direct", wmLichWeapons.getUrlName(), (String) param.getOrDefault("element", null),
                    (Boolean) param.getOrDefault("ephemera", null), (Integer) param.getOrDefault("damageMin", null), (Integer) param.getOrDefault("damageMax", null),
                    null, AuctionsSortByEnum.PRICE_ASC.getType());
            // 判断排序
            warframeMarketLichAuctionDTOList.forEach(warframeMarketItemsOrderDTO -> {
                warframeMarketItemsOrderDTO.setSort(this.getSortByStatus(warframeMarketItemsOrderDTO.getOwner().getStatus()));
            });
            // 排序 ingame-1 online-2 offline-3，后排序价格
            warframeMarketLichAuctionDTOList = warframeMarketLichAuctionDTOList.stream()
                    .sorted(Comparator.comparing(WarframeMarketLichAuctionDTO::getSort).thenComparing(WarframeMarketLichAuctionDTO::getStartingPrice))
                    .collect(Collectors.toList());
            List<List<WarframeMarketLichAuctionDTO>> warframeMarketLichAuctionDTOListSplit = ListUtil.split(warframeMarketLichAuctionDTOList, 5);
            List<WarframeMarketLichAuctionTemplateDTO> warframeMarketLichAuctionTemplateDTOList = new ArrayList<>();
            for (int i = 0; i < warframeMarketLichAuctionDTOListSplit.size(); i++) {
                List<WarframeMarketLichAuctionDTO> warframeMarketLichAuctionDTOS = warframeMarketLichAuctionDTOListSplit.get(page - 1);
                for (int i1 = 0; i1 < warframeMarketLichAuctionDTOS.size(); i1++) {
                    WarframeMarketLichAuctionDTO warframeMarketLichAuctionDTO = warframeMarketLichAuctionDTOS.get(i1);
                    WarframeMarketLichAuctionTemplateDTO warframeMarketLichAuctionTemplateDTO = new WarframeMarketLichAuctionTemplateDTO();
                    warframeMarketLichAuctionTemplateDTO.setElement(LichElementEnum.getNameByType(warframeMarketLichAuctionDTO.getItem().getElement()));
                    if (warframeMarketLichAuctionDTO.getItem().getHavingEphemera()) {
                        warframeMarketLichAuctionTemplateDTO.setEphemeraName(this.getEphemeraNameByElement(warframeMarketLichAuctionDTO.getItem().getElement()));
                    } else {
                        warframeMarketLichAuctionTemplateDTO.setEphemeraName("无幻纹");
                    }
                    warframeMarketLichAuctionTemplateDTO.setDamage(String.valueOf(warframeMarketLichAuctionDTO.getItem().getDamage()));
                    warframeMarketLichAuctionTemplateDTO.setStartingPrice(String.valueOf(warframeMarketLichAuctionDTO.getStartingPrice()));
                    warframeMarketLichAuctionTemplateDTO.setBuyoutPrice(String.valueOf(warframeMarketLichAuctionDTO.getBuyoutPrice()));
                    warframeMarketLichAuctionTemplateDTO.setTopBid(warframeMarketLichAuctionDTO.getTopBid() == null ? "暂无":String.valueOf(warframeMarketLichAuctionDTO.getTopBid()));
                    warframeMarketLichAuctionTemplateDTO.setIngameName(warframeMarketLichAuctionDTO.getOwner().getIngameName());
                    warframeMarketLichAuctionTemplateDTO.setStatus(this.getStatusDesc(warframeMarketLichAuctionDTO.getOwner().getStatus()));
                    warframeMarketLichAuctionTemplateDTOList.add(warframeMarketLichAuctionTemplateDTO);
                }
                break;
            }
            if (CollUtil.isEmpty(warframeMarketLichAuctionTemplateDTOList)) {
                String msg = "[CQ:at,qq=" + userId + "]\n目前未在warframe.market查询到相关交易";
//                QQClientUtils.sendGroupMsg(msg, userId, groupId, isGroup);
                return;
            }
            Map<String, Object> templateParam = new HashMap<>();
            templateParam.put("param", param.get("lichName"));
            templateParam.put("itemName", wmLichWeapons.getItemName());
            templateParam.put("auctionList", warframeMarketLichAuctionTemplateDTOList);
            try {
                HtmlToImageUtils.htmlToImage("lichAuctionTemplate.html", templateParam, "src/main/resources/picture/lichAuction.png", 2200);
                File file = new File("src/main/resources/picture/lichAuction.png");
                String encode = Base64.encode(file);
                String msg = "[CQ:at,qq=" + userId + "]\n[CQ:image,file=base64://" + encode+ ",type=show,subType=0]";
                QQClientUtils.sendMsg(msg, userId, groupId, isGroup);
                qGroupUserOperationQuantityService.statisticsOperationQuantityByType(groupId, userId, OperationTypeEnum.WML);
            } catch (IOException | TemplateException | ParserConfigurationException | SAXException e) {
                log.error("获取玄骸展示模板失败:{}", e.getMessage(), e);
//                QQClientUtils.sendGroupMsg("[CQ:at,qq=" + userId + "]\n获取玄骸展示模板失败，请联系制作人", userId, groupId, isGroup);
            }
            return;
        }
        if (wmLichWeaponsList.size() > 1) {
            StringBuilder msg = new StringBuilder("[CQ:at,qq=" + userId + "]\n以下有多个匹配的结果，请确认你要查询的物品：\n");
            for (WmLichWeapons wmLichWeapons : wmLichWeaponsList) {
                msg.append("【").append(wmLichWeapons.getItemName()).append("】  ");
            }
//            msg.append("\n如果你想要关键词匹配，请输入：添加关键词匹配 [匹配物品名称] [关键词]");
//            QQClientUtils.sendGroupMsg(msg.toString(), userId, groupId, isGroup);
//        } else {
//            QQClientUtils.sendGroupMsg("[CQ:at,qq=" + userId + "]\n无法找到你想要查询的物品，请确认名称是否准确", userId, groupId, isGroup);
        }
    }

    /**
     * 解析参数
     * @return Map<String, String>
     */
    private Map<String, Object> getParam(String text, Long groupId, Long userId, Boolean isGroup) {
        Map<String, Object> result = new HashMap<>();
        String[] wmlS = text.replace("wml ", "").split("] \\[");
        String lichName = null;
        Integer damageMin = null;
        Integer damageMax = null;
        String element = null;
        Boolean ephemera = null;
        for (int i = 0; i < wmlS.length; i++) {
            // 第一位是赤毒名称
            if (i == 0 && StrUtil.isNotEmpty(wmlS[i])) {
                lichName = wmlS[i].replace("[", "").replace("]", "");
            }
            // 第二位是赤毒加成数值
            if (i == 1 && StrUtil.isNotEmpty(wmlS[i])) {
                String[] damageStrList = wmlS[i].replace("[", "").replace("]", "").split("-");
                if (damageStrList.length == 1) {
                    damageMin = Integer.valueOf(damageStrList[0]);
                    damageMax = Integer.valueOf(damageStrList[0]);
                } else if (damageStrList.length == 2) {
                    for (int i1 = 0; i1 < damageStrList.length; i1++) {
                        // 第一位是赤毒加成数值最小值
                        if (i1 == 0) {
                            damageMin = Integer.valueOf(damageStrList[i1]);
                        }
                        // 第二位是赤毒加成数值最大值
                        if (i1 == 1) {
                            damageMax = Integer.valueOf(damageStrList[i1]);
                        }
                    }
                } else {
                    QQClientUtils.sendMsg("[CQ:at,qq=" + userId + "]\n请输入正确的加成数值格式\n", userId, groupId, isGroup);
                }
            }
            // 第三位是赤毒属性
            if (i == 2 && StrUtil.isNotEmpty(wmlS[i])) {
                element = LichElementEnum.getTypeByName(wmlS[i].replace("[", "").replace("]", ""));
            }
            // 第四位是赤毒是否携带幻纹
            if (i == 3 && StrUtil.isNotEmpty(wmlS[i])) {
                switch (wmlS[i].replace("[", "").replace("]", "")) {
                    case "是" -> ephemera = true;
                    case "否" -> ephemera = false;
                }
            }
        }
        result.put("lichName", lichName);
        result.put("damageMin", damageMin);
        result.put("damageMax", damageMax);
        result.put("element", element);
        result.put("ephemera", ephemera);
        return result;
    }

    /**
     * 解析状态判断排序
     * @param status offline ingame online
     * @return String
     */
    private Integer getSortByStatus(String status) {
        return switch (status) {
            case "offline" -> 3;
            case "ingame" -> 1;
            case "online" -> 2;
            default -> 4;
        };
    }

    /**
     * 解析状态为中文
     * @param status offline ingame online
     * @return String
     */
    private String getStatusDesc(String status) {
        return switch (status) {
            case "offline" -> "离线";
            case "ingame" -> "游戏中";
            case "online" -> "在线";
            default -> "";
        };
    }

    /**
     * 通过属性获取幻纹名称
     * @param element element
     * @return String
     */
    private String getEphemeraNameByElement(String element) {
        return switch (element) {
            case "impact" -> "复仇震波幻纹";
            case "heat" -> "复仇火焰幻纹";
            case "cold" -> "复仇冰冻幻纹";
            case "electricity" -> "复仇充电幻纹";
            case "toxin" -> "复仇毒素幻纹";
            case "magnetic" -> "复仇吸引幻纹";
            case "radiation" -> "复仇骗术幻纹";
            default -> "无幻纹";
        };
    }
}
